#!/usr/bin/python
import string
import sys
import pygame
import random
from pygame.locals import *
import glob

WIDOCZNE_WIERSZE = 16
SCALE = 2

def turn_right(kx, ky):
    return -ky, kx

def turn_left(kx, ky):
    return ky, -kx

class Element:
    destroyable_by_laser = False
    destroyable_by_blaster = False
    destroyable_by_bomb = False
    movable = False
    useable = False # (collectable, pushable)
    slowness = 2

    def __repr__(self):
        return "%s at %d %d" % (self.__class__.__name__, self.x, self.y)

    def __init__(self, plansza, x, y):
        self.offset = 0 # licznik animacji
        self.x = x
        self.y = y
        self.plansza = plansza
        self.plansza.insert(x, y, self)
        self.do_zniszczenia = False

    def get_tile(self):
        tiles = self.get_tiles()
        tile = tiles[self.offset / self.slowness]
        self.offset = (self.offset + 1) % (len(tiles) * self.slowness)
        return tile
        
    def get_tiles(self):
        return self.tiles

    def draw(self):
        y = (self.y * 16 - self.plansza.yoffset)
        t = self.get_tile()
        if y> -16 and y < 16 * WIDOCZNE_WIERSZE:
            self.plansza.screen.blit(dane, ((self.x * 16) * SCALE, y * SCALE),\
            (t * 16 * SCALE, 0, 16 * SCALE, 16 * SCALE))

    def destroy(self, source):
        if ((isinstance(source, Bomba) and self.destroyable_by_bomb)\
        or ((isinstance(source, Pocisk) or source == None) and self.destroyable_by_laser)\
        or (isinstance(source, Plansza))):
            Chmurka(self.plansza, self.x, self.y)
        elif (isinstance(source, Blaster) and self.destroyable_by_blaster):
            self.plansza.remove(self)

    def push(self, kx, ky):
        return False

    def ruch_o(self, kx, ky):
        if kx == 0 and ky == 0:
            return False
        nx, ny = self.x + kx, self.y + ky
        if self.plansza[ny][nx] == None:
            self.plansza[ny][nx] = self.plansza[self.y][self.x]
            self.plansza[self.y][self.x] = None
            self.x, self.y = nx, ny
            self.kx, self.ky = kx, ky
            return True
        elif isinstance(self, ElementRuchomy) and isinstance(self.plansza[ny][nx], Niszczyrzeka):
            self.plansza.remove(self)
            return True

class Gruz(Element):
    tiles = (9, )
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True

class Wall(Element):
    tiles = (0, 1, 2, 3, 4, 5, 6, 7, )

    def get_tiles(self):
#        return self.tiles[(self.plansza.current_level) % 8],
#        return self.tiles[self.i],
        return self.tiles[0],

    def destroy(self, source):
        pass

class Nicosc(Wall):
    tiles = (8, )

class Niszczyrzeka(Element):
    slowness = 8
    tiles = (30, 31, )
    destroyable_by_laser = True
    destroyable_by_bomb = True

    def push(self, robbo):
        self.plansza.remove(robbo)
        return True

class Srubka(Element):
    tiles = (12, )
    destroyable_by_bomb = True

    def push(self, kx, ky):
        self.plansza.statek.wkrec_srubke()
        self.plansza.remove(self)
#        self.plansza.show_status()
        return True

class DodatkoweZycie(Element):
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True
    tiles = (24, )

    def push(self, kx, ky):
        self.plansza.robbo.zycia += 1
        self.plansza.remove(self)
        return True

class Kluczyk(Element):
    destroyable_by_bomb = True
    tiles = (16, )

    def push(self, kx, ky):
        self.plansza.robbo.kluczyki += 1
        self.plansza.remove(self)
#        self.plansza.show_status()
        return True
    
class Bateria(Element):
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True
    tiles = (13, )

    def push(self, kx, ky):
        self.plansza.robbo.bateria += 9
        self.plansza.remove(self)
#        self.plansza.show_status()
        return True

class Drzwi(Element):
    destroyable_by_bomb = True
    tiles = (17, )

    def push(self, kx, ky):
        if self.plansza.robbo.kluczyki > 0:
            self.plansza.robbo.kluczyki -= 1
            self.plansza.remove(self)
#            self.plansza.show_status()
        return False
    
class Chmurka(Element):
    slowness = 1
    tiles = (51, 50, 51, 52, 53, )

    def __init__(self, *args, **kwargs):
      Element.__init__(self, *args, **kwargs)
      self.offset = random.randrange(3) * self.slowness

    def draw(self):
        Element.draw(self)
        if self.offset == 0:
            self.remove()

    def destroy(self, source):
        pass
    
    def remove(self):
        self.plansza.remove(self)

class ChmurkaTeleportowa(Chmurka):
    tiles = (50, 51, )

    def __init__(self, *args, **kwargs):
        Element.__init__(self, *args, **kwargs)
        self.offset = 0

class RobboSpawn(Element):
    tiles = (20, 51, 50, )
    def __init__(self, plansza, x, y):
        Element.__init__(self, plansza, x, y)
        self.plansza.robbo.x = self.x
        self.plansza.robbo.y = self.y
    
    def draw(self):
        Element.draw(self)
        if self.offset == 0:
            self.plansza.insert(self.x, self.y, self.plansza.robbo)

class TeleportRobboSpawn(RobboSpawn):
    tiles = (51, 50, )
            
class LaserBody(Element):
    tiles = (54, 55, 56, 57, )

    def __init__(self, plansza, x, y, laser):
        Element.__init__(self, plansza, x, y)
        self.laser = laser

    def get_tiles(self):
        return self.tiles[0:2] if self.laser.kx else self.tiles[2:4]

class Teleport(Element):
    tiles = (22, 23, )
  
    def next(self):
        teleports = self.plansza.filtr_items(Teleport)
        i = teleports.index(self)
        while 1:
            i = (i + 1) % len(teleports)
            if (teleports[i].id == self.id):
                break
        return teleports[i]
    
    def push(self, kx, ky):
        dest = self.next()

        def try_spawn_at(kx, ky):
            nx, ny = dest.x + kx, dest.y + ky
            if self.plansza[ny][nx] == None:
                #RobboSpawn zmienia tez wspolrzedne plansza.robbo
                #wiec usuwamy z planszy sami
                self.plansza.remove(self.plansza.robbo)
                TeleportRobboSpawn(self.plansza, nx, ny)
                return True

        oldx, oldy = self.plansza.robbo.x, self.plansza.robbo.y
        if try_spawn_at(kx, ky) or try_spawn_at(ky, kx) or \
            try_spawn_at(-ky, -kx) or try_spawn_at(-kx, -ky):
            ChmurkaTeleportowa(self.plansza, oldx, oldy)
        else:
            TeleportRobboSpawn(self.plansza, oldx, oldy)
      
class Teleport1(Teleport):

    def __init__(self, plansza, x, y, numer = 1):
        self.id = numer
        Teleport.__init__(self, plansza, x, y)

class Teleport2(Teleport):

    def __init__(self, plansza, x, y, numer = 2):
        self.id = numer
        Teleport.__init__(self, plansza, x, y)

class Teleport3(Teleport):

    def __init__(self, plansza, x, y, numer = 3):
        self.id = numer
        Teleport.__init__(self, plansza, x, y)

class Teleport4(Teleport):

    def __init__(self, plansza, x, y, numer = 4):
        self.id = numer
        Teleport.__init__(self, plansza, x, y)

class Teleport5(Teleport):

    def __init__(self, plansza, x, y, numer = 5):
        self.id = numer
        Teleport.__init__(self, plansza, x, y)

class Teleport6(Teleport):

    def __init__(self, plansza, x, y, numer = 6):
        self.id = numer
        Teleport.__init__(self, plansza, x, y)

class ElementRuchomy(Element):

    def push(self, kx, ky):
        return self.ruch_o(kx, ky)

class Statek(ElementRuchomy):
    tiles = (20, 21, )

    def __init__(self, plansza, x, y):
        self.count = 0
        self.required = 0
        ElementRuchomy.__init__(self, plansza, x, y)

    def get_tiles(self):
        return self.tiles if self.count >= self.required else (self.tiles[0],)

    def wymagane_srubki(self, n):
        self.required = n
        self.count = 0
        if self.count >= self.required:
            self.plansza.start_shake(4)
      
    def wkrec_srubke(self):
        self.count += 1
        if self.count >= self.required:
            self.plansza.start_shake(4)

    def push(self, kx, ky):
        if self.count >= self.required:
            self.plansza.next_level()
            return True
        else:
            return ElementRuchomy.push(self, kx, ky)

    def destroy(self, source): 
        pass

class Skrzynka(ElementRuchomy):
    destroyable_by_bomb = True
    tiles = (10, )

class Niespodzianka(ElementRuchomy):
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True
    tiles = (25, )

    def destroy(self, source):
        if isinstance(source, Pocisk) or source == None:
            los = random.choice(['$', 'T', 'l', 'r', 'k', 'B', '?'])
            element = self.plansza.item_class[los](self.plansza, self.x, self.y)
#            self.plansza.insert(element)
        else:
            self.plansza.remove(self) 
#        ElementRuchomy.destroy(self, source)
#        if self.plansza[self.y][self.x] == self:
#            self.plansza.create_random(self.x, self.y)

class Bomba(ElementRuchomy):
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True
    tiles = (14, )

    def __init__(self, *args, **kwargs):
        ElementRuchomy.__init__(self, *args, **kwargs)
        self.odpalona = 0
    
    def destroy(self, source = None):
        x, y = self.x, self.y
        if not isinstance(source, Blaster):
            self.plansza.destroy(x + 1, y, self)
            self.plansza.destroy(x - 1, y, self)
            self.plansza.destroy(x, y - 1, self)
            self.plansza.destroy(x, y + 1, self)
            self.plansza.destroy(x - 1, y - 1, self)
            self.plansza.destroy(x + 1, y - 1, self)
            self.plansza.destroy(x - 1, y + 1, self)
            self.plansza.destroy(x + 1, y + 1, self)
        ElementRuchomy.destroy(self, self)

class Aktor(Element):

    def __repr__(self):
        return "%s at %d %d (%d %d)"%(self.__class__.__name__,self.x, self.y, self.kx, self.ky)

    def __init__(self, plansza, x, y, kx = 0, ky = 0):
        Element.__init__(self, plansza, x, y)
        self.kx = kx
        self.ky = ky

    def ruch(self):
        pass

class Potworek(Aktor):
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True

class Pocisk(Aktor):
    tiles = (54, 55, 56, 57, )

    def ruch(self):
        if not self.ruch_o(self.kx,self.ky):
            self.destroy(self.plansza)
            self.plansza[self.y + self.ky][self.x + self.kx].destroy(self)

    def get_tiles(self):
        if self.kx:
            return self.tiles[0:2]
        else:
            return self.tiles[2:4]

class Laser(Pocisk):

    def __init__(self, *args, **kwargs):
        Pocisk.__init__(self, *args, **kwargs)
        self.bx = self.x
        self.by = self.y
        self.wraca = False
            
    def ruch(self):
        if not self.wraca:
            nx, ny = self.x + self.kx, self.y + self.ky
            if (self.plansza[ny][nx] == None):
                LaserBody(plansza,self.x, self.y, self)
                self.x, self.y = nx, ny
                self.plansza.insert(self.x, self.y, self)
            else:
                self.plansza[ny][nx].destroy(self)
                self.wraca = True
                self.kx *= -1
                self.ky *= -1
                # trafienie potworka, robbo, bomby, sciany, chmurki
        else:
            self.plansza[self.y][self.x] = None
            if self.x != self.bx or self.y != self.by:
                self.x += self.kx
                self.y += self.ky
            else:
                #todo - remove nie powinno byc potrzebne (a jest)
                self.plansza.remove(self)
                Element.destroy(self, Plansza)              

class Blaster(Pocisk):

    def ruch(self):
        ox, oy = self.x, self.y
        nx, ny = self.x + self.kx, self.y + self.ky
        target = self.plansza[ny][nx]
        if target == None or target.destroy(self):
            self.plansza[ny][nx] = self.plansza[oy][ox]
            self.plansza[oy][ox] = None
            Chmurka(self.plansza, ox, oy).offset = 0
            self.x, self.y = nx, ny
        else:
            Element.destroy(self, None)
    
    def get_tiles(self):
        return (51, )

class Magnes(Aktor):
    destroyable_by_laser = False
    destroyable_by_blaster = False
    destroyable_by_bomb = False
    tiles = (18, 19, )

    def ruch(self):
        if (self.y == self.plansza.robbo.y):
            nx, ny = self.x + self.kx, self.y
            while 1:
                if plansza[ny][nx] == None:
                    nx += self.kx
                elif isinstance(self.plansza[ny][nx], Robbo):
                    self.plansza.robbo.idz(-self.kx, 0)
                    self.plansza.robbo.unieruchom()
                    break
                else:
                    break

class MagnesLewo(Magnes):

    def __init__(self, plansza, x, y):
        Magnes.__init__(self, plansza, x, y, kx = 1, ky = 0)

    def get_tiles(self):
        return (18, )

class MagnesPrawo(Magnes):

    def __init__(self, plansza, x, y):
        Magnes.__init__(self, plansza, x, y, kx = -1, ky = 0)

    def get_tiles(self):
        return (19, )

class Dzialko(Aktor):
    tiles = (26, 27, 28, 29, )
    destroyable_by_bomb = True
    ammo = Pocisk

    def get_tiles(self):
        if self.kx == -1:
            return self.tiles[0:1]
        elif self.kx == 1:
            return self.tiles[2:3]
        elif self.ky == -1:
            return self.tiles[1:2]
        else:
            return self.tiles[3:4]

    def ruch(self):
        nx, ny = self.x + self.kx, self.y + self.ky
        if random.randrange(100) < 10:
            if self.plansza[ny][nx] == None:
                p = self.ammo(self.plansza, nx, ny, self.kx, self.ky)
            else:
                self.plansza[ny][nx].destroy(None)

class DzialkoPrawo(Dzialko):

    def __init__(self, plansza, x, y):
        Dzialko.__init__(self, plansza, x, y, kx = 1, ky = 0)

class DzialkoLewo(Dzialko):

    def __init__(self, plansza, x, y):
        Dzialko.__init__(self, plansza, x, y, kx = -1, ky = 0)

class DzialkoGora(Dzialko):

    def __init__(self, plansza, x, y):
        Dzialko.__init__(self, plansza, x, y, kx = 0, ky = -1)

class DzialkoDol(Dzialko):

    def __init__(self, plansza, x, y):
        Dzialko.__init__(self, plansza, x, y, kx = 0, ky = 1)

class DzialkoLaserowe(Dzialko):
    ammo = Laser
  
class DzialkoLaserowePrawo(DzialkoLaserowe):

    def __init__(self, plansza, x, y):
        DzialkoLaserowe.__init__(self, plansza, x, y, kx = 1, ky = 0)

class DzialkoLaseroweLewo(DzialkoLaserowe):

    def __init__(self, plansza, x, y):
        DzialkoLaserowe.__init__(self, plansza, x, y, kx = -1, ky = 0)

class DzialkoLaseroweGora(DzialkoLaserowe):

    def __init__(self, plansza, x, y):
        DzialkoLaserowe.__init__(self, plansza, x, y, kx = 0, ky = -1)

class DzialkoLaseroweDol(DzialkoLaserowe):

    def __init__(self, plansza, x, y):
        DzialkoLaserowe.__init__(self, plansza, x, y, kx = 0, ky = 1)
          
class DzialkoObrotowe(Dzialko):

    def __init__(self, plansza, x, y):
        Dzialko.__init__(self, plansza, x, y, kx = 0, ky = 1)

    def ruch(self):
        celx, cely = self.x + self.kx, self.y + self.ky
        los = random.randint(1, 40)
        if los in [1, 2]:
            self.kx, self.ky = turn_right(self.kx, self.ky)
        elif los in [3, 4]:
            self.kx, self.ky = turn_left(self.kx, self.ky)

        Dzialko.ruch(self)

class Gacek(Potworek):
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True

    def ruch(self):
        if not self.ruch_o(self.kx, self.ky): # zwrot
            self.ky *= -1
            self.kx *= -1

class GacekPionowy(Gacek):
    tiles = (38, 39, )

    def __init__(self, plansza, x, y):
        Gacek.__init__(self, plansza, x, y, ky = 1)

class GacekPoziomy(Gacek):
    tiles = (38, 39, )

    def __init__(self, plansza, x, y):
        Gacek.__init__(self, plansza, x, y, kx = 1)

class GacekStrzelajacy(GacekPoziomy):
    tiles = (40, 41, )

    def ruch(self):
        los = random.randint(0, 8)
        if los in range(5):
            celx, cely = self.x , self.y + 1
            if self.plansza[cely][celx] == None:
                p = Pocisk(self.plansza, celx, cely, 0, 1)
            else:
                self.plansza[cely][celx].destroy(self)
        GacekPoziomy.ruch(self)

class DzialkoRuchome(Dzialko): # ruch poziomy
    tiles = (58, )

    def __init__(self, plansza, x, y):
        Dzialko.__init__(self, plansza, x, y, kx = 1)

    def ruch(self):
        los = random.randint(0, 8)
        if los in range(5):
            celx, cely = self.x , self.y - 1
            if self.plansza[cely][celx] == None:
                p = Pocisk(self.plansza, celx, cely, 0, -1)
            else:
                self.plansza[cely][celx].destroy(self)
        Dzialko.ruch(self)

class DiabelekPrawicowy(Potworek):
    tiles = (34, 35, )

    def __init__(self, plansza, x, y):
        Potworek.__init__(self, plansza, x, y)
        self.kx, self.ky = 0, -1
        kx = 0
        ky = 1
        for dir in range(4):
            self.kx, self.ky = turn_left(kx, ky)
            if plansza[self.y + ky][self.x + kx]:
                return
        kx, ky = self.kx, self.ky

    def ruch(self):
        rx, ry = turn_right(self.kx, self.ky)
        lx, ly = turn_left(self.kx, self.ky)
        bx, by = -self.kx, -self.ky
        infront = self.plansza[self.y + self.ky][self.x + self.kx]
        if isinstance(infront,Pocisk) and infront.kx == -self.kx and infront.ky == -self.ky:
            return

        self.ruch_o(rx, ry) or self.ruch_o(self.kx, self.ky) or \
        self.ruch_o(lx, ly) or self.ruch_o(bx, by)

class DiabelekLewicowy(Potworek):
    tiles = (32, 33, )
    def __init__(self, plansza, x, y):
        Potworek.__init__(self, plansza, x, y)
        self.kx, self.ky = 0, -1
        kx = 0
        ky = 1
        for dir in range(4):
            self.kx, self.ky = turn_right(kx, ky)
            if plansza[self.y + ky][self.x + kx]:
                return
        kx, ky = self.kx, self.ky

    def ruch(self):
        rx, ry = turn_right(self.kx, self.ky)
        lx, ly = turn_left(self.kx, self.ky)
        bx, by = -self.kx, -self.ky

        infront = self.plansza[self.y + self.ky][self.x + self.kx]
        if isinstance(infront, Pocisk) and infront.kx == -self.kx and infront.ky == -self.ky:
            return
    
        self.ruch_o(lx, ly) or self.ruch_o(self.kx, self.ky) or \
        self.ruch_o(rx, ry) or self.ruch_o(bx, by)

class Robbo(Aktor):
    destroyable_by_laser = True
    destroyable_by_blaster = True
    destroyable_by_bomb = True
    slowness = 1
    tiles = (42, 43, 44, 45, 46, 47, 48, 49, )

    def __init__(self, plansza, x, y):
        Aktor.__init__(self, plansza, x, y)
        self.plansza = plansza
        self.zycia = 4
        self.srubki = 0
        self.kluczyki = 0
        self.bateria = 0
        self.fire = False
        self.last = self.tiles[6:8]
        self.blokada = False

    def get_tile(self):
        if self.kx == -1:
            self.last = self.tiles[0:2]
        elif self.kx == 1:
            self.last = self.tiles[4:6]
        elif self.ky == -1:
            self.last = self.tiles[2:4]
        elif self.ky == 1:
            self.last = self.tiles[6:8]
        tile = self.last[self.offset / self.slowness]
        if self.kx or self.ky:
            self.offset = (self.offset + 1) % (len(self.last) * self.slowness)
        return tile
        
    def unieruchom(self):
        self.blokada = True

    def idz(self, kx, ky):
        if self.blokada == False:
                self.kx = kx
                self.ky = ky

    def kolizja(self):
        if isinstance(self.plansza[self.y - 1][self.x], Potworek) or \
        isinstance(self.plansza[self.y + 1][self.x], Potworek) or \
        isinstance(self.plansza[self.y][self.x - 1], Potworek) or \
        isinstance(self.plansza[self.y][self.x + 1], Potworek):
            self.destroy(plansza)
        if self.plansza[self.y + self.ky][self.x + self.kx] != None and self.blokada:
            self.destroy(plansza)

    def ruch(self):
        if self.kx == 0 and self.ky == 0:
            return
        z_przodu = self.plansza[self.y + self.ky][self.x + self.kx]
        if self.fire:
            if self.bateria:
                self.bateria -= 1
                if z_przodu == None:
                    pocisk = Pocisk(self.plansza, self.x + self.kx, self.y + self.ky, self.kx, self.ky)
                else:
                    z_przodu.destroy(None)
#                    self.plansza[self.y + self.ky][self.x + self.kx].destroy(self)
        elif (z_przodu == None) or z_przodu.push(self.kx, self.ky):
            self.ruch_o(self.kx, self.ky)

    def na_planszy(self):
        return self.plansza[self.y][self.x] == self
    
    def destroy(self,source = None):
        Aktor.destroy(self, source)
        self.plansza.reload()
#        RobboChmurka(self.plansza, self.x, self.y)
      
class Plansza(list):

    item_class = {'R':RobboSpawn,
                  '1':GacekPoziomy,
                  '2':GacekPionowy,
                  '3':DiabelekPrawicowy,
                  '4':DiabelekLewicowy,
                  '5':GacekStrzelajacy,
                  '#':Wall,
                  'n':Nicosc,
                  '$':Skrzynka,
                  'l':Bateria,
                  'T':Srubka,
                  'r':DodatkoweZycie,
                  '?':Niespodzianka,
                  'D':Drzwi,
                  'B':Bomba,
                  'k':Kluczyk,
                  'E':Statek,
                  '-':Niszczyrzeka,
                  'c':Chmurka,
                  't':Teleport1,
                  'u':Teleport2,
#                  't':Teleport3,
#                  't':Teleport4,
#                  't':Teleport5,
#                  't':Teleport6,
                  'M':MagnesLewo,
                  'm':MagnesPrawo,
                  '9':DzialkoRuchome,
                  '>':DzialkoPrawo,
                  '<':DzialkoLewo,
                  'v':DzialkoDol,
                  '^':DzialkoGora,
                  'a':DzialkoLaseroweLewo,
                  'd':DzialkoLaserowePrawo,
                  'w':DzialkoLaseroweGora,
                  's':DzialkoLaseroweDol,
                  '0':DzialkoObrotowe,
                  'g':Gruz,
                  }

    punkty     = {'r':100,
                  'k':50,
                  'l':25,
                  'T':15,
                 }

    def __init__(self, screen, dane, ui_bg, ui):
        self.screen = screen
        self.dane = dane
        self.ui = ui
        self.ui_bg = ui_bg
        self.robbo = None
        self.statek = None
        self.level_files = sorted(glob.glob("level*.txt"))
        self.current_level = 0
        self.bg_color = (random.randrange(256), random.randrange(256), 167)
        self.punkty = 0
        self.wymiar_x = 16
        self.wymiar_y = 31
        self.game_field = Rect((0, 0), (256 * SCALE, 16 * WIDOCZNE_WIERSZE * SCALE))
        self.score_field = Rect((0, 16 * WIDOCZNE_WIERSZE * SCALE), (256 * SCALE, 32 * SCALE))

#        while self:
#            self.pop()

        for _y in range(self.wymiar_y):
            self.append(list((None, ) * self.wymiar_x))


    def items(self):
        for y in range(self.wymiar_y):
            for x in range(self.wymiar_x):
                if self[y][x]:
                    yield self[y][x]

    def filtr_items(self, id):
        lista = filter(lambda item:isinstance(item, id), self.items())
        return lista

    def clear(self):
        for _y in range(self.wymiar_y):
            for _x in range(self.wymiar_x):
                self[_y][_x] = None

    def load(self):
        plik = self.level_files[self.current_level]
        self.shake_cnt = 0
        self.reloading = False

        self.clear()

        f = open(plik,"r") # plik -> _dane
        _dane = f.read().split('\n')
        f.close
        
#        while self:
#          self.pop()
          
        self.aktors = []
        self.pociski=[]
        self.damaged_tiles=[]

        self.yoffset = 0
        self.reqoffs = 0
        
        self.robbo = Robbo(self, 0, 0)

        y = 0
        for line in _dane:
            if y in range(self.wymiar_y):
                x = 0
                for element in line:
                    if x in range(self.wymiar_x):
                        if element in self.item_class:
                            element = self.item_class[element](self, x, y)
                    else:
                        pass
                    x += 1
            else:
                pass            
            y += 1
        
        print self.statek, self.robbo
        self.statek.wymagane_srubki(len(self.filtr_items(Srubka)))
                    
    def start_shake(self, amount):
        self.shake_cnt = amount
        self.old_bg_color = self.bg_color
        self.bg_color = (255, 255, 255)
      
    def shake(self):
      if self.shake_cnt:
          self.shake_cnt -= 1
          if not self.shake_cnt:
              self.bg_color = self.old_bg_color


#    def create_random(self, x, y):
#        from random import choice
#        while True:
#            cls = choice(self.item_class.values())
#            if cls not in (Robbo,):
#                return cls(self,x,y)
      
    def insert(self, x, y, item):
        if self[y][x] != None:
            self.remove(self[y][x])
        self[y][x] = item
        if isinstance(item, Statek):
            self.statek = item
        elif isinstance(item, Robbo):
            self.robbo = item
        elif isinstance(item, Pocisk):
            self.pociski.append(item)
        elif isinstance(item, Aktor):
            self.aktors.append(item)

    def remove(self, item):
        if isinstance(item, Pocisk):
            self.pociski.remove(item)
        elif isinstance(item, Aktor) and item in self.aktors:
            self.aktors.remove(item)
        self[item.y][item.x] = None

    def ruch_aktorow(self):
        for p in self.aktors:
            p.ruch()
      
    def ruch_pociskow(self):
        for p in self.pociski:
            p.ruch()

    def aplikuj_zniszczenia(self):
        damaged_tiles = self.damaged_tiles
        self.damaged_tiles = []
        for x, y, source in damaged_tiles:
            item = self[y][x]
            if item:
                item.destroy(source)
            else:
                Chmurka(self, x, y)

    def destroy(self, x, y, source = None):
        if x >= 0 and y >= 0 and x < self.wymiar_x and y < self.wymiar_y:
            self.damaged_tiles.append((x, y, source))

    def reload(self):
        self.reloading = True
      
    def draw(self):
        self.screen.fill(self.bg_color, self.game_field)
        for item in self.items():
            item.draw()
#        self.screen.fill((0, 0, 0), self.score_field)
        self.screen.blit(ui_bg, (0, 16 * WIDOCZNE_WIERSZE * SCALE), (0, 0, 256 * SCALE, 32 * SCALE))
        punkty1 = self.punkty % 10
        punkty2 = ((self.punkty - punkty1) / 10) % 10
        punkty3 = 0
        punkty4 = 0
        srubki1 = 0
        srubki2 = 0
        laser1 = 0
        laser2 = 0
        zycia1 = 0
        zycia2 = 0
        poziom1 = 0
        poziom2 = 0
        self.screen.blit(ui, (0, 16 * WIDOCZNE_WIERSZE * SCALE), (0, 0, 256 * SCALE, 32 * SCALE))

    def next_level(self):
        if self.current_level < len(self.level_files) - 1:
            self.current_level += 1
            self.load()
        else:
            print "GAME OVER"
        
    def show_status(self):
        print "Level:%2d Srubki:%2d Kluczyki:%2d Naboje:%2d"%(self.current_level, self.statek.required - self.statek.count, self.robbo.kluczyki, self.robbo.bateria)
    
    def przewin(self):
        if self.robbo.y - self.reqoffs / 16 >= WIDOCZNE_WIERSZE - 3:
            self.reqoffs += 48
            if self.reqoffs > (self.wymiar_y - WIDOCZNE_WIERSZE) * 16: 
                self.reqoffs = (self.wymiar_y - WIDOCZNE_WIERSZE) * 16
        elif (self.robbo.y - (self.reqoffs + 15) / 16) < 2:
            self.reqoffs -= 48
        if self.reqoffs < 0:
            self.reqoffs = 0    
        if self.yoffset < self.reqoffs:
            self.yoffset += 4
        elif self.yoffset > self.reqoffs:
            self.yoffset -= 4


        pygame.display.flip()
    
def init_sound():
    pass

def zdarzenia(events, plansza):
    global kx, ky
    for event in events:
        if event.type == QUIT:
            pygame.display.quit()
            return 0
        elif plansza.robbo and (event.type == KEYDOWN or event.type == KEYUP):
            v = int(event.type == KEYDOWN)
            if event.key == K_UP:
                plansza.robbo.idz(0, -v)
            elif event.key == K_RIGHT:
                plansza.robbo.idz(v, 0)
            elif event.key == K_DOWN:
                plansza.robbo.idz(0, v)
            elif event.key == K_LEFT:
                plansza.robbo.idz(-v, 0)
            elif event.key == K_SPACE:
                plansza.robbo.fire = v
            elif event.key == K_ESCAPE:
                plansza.robbo.destroy(plansza)
            elif event.key == K_n and event.type == KEYDOWN:
                plansza.next_level()            
    return 1

pygame.init()
init_sound()
pygame.display.set_caption('PyROBBO')

screen = pygame.display.set_mode((16 * 16 * SCALE, (WIDOCZNE_WIERSZE + 2) * 16 * SCALE))
dane = pygame.image.load('dane.png').convert()
dane = pygame.transform.scale(dane, (dane.get_width() * SCALE, dane.get_height() * SCALE))
dane.set_colorkey((255, 0, 255))
ui_bg = pygame.image.load('ui_bg.png').convert()
ui_bg = pygame.transform.scale(ui_bg, (ui_bg.get_width() * SCALE, ui_bg.get_height() * SCALE))
ui_bg.set_colorkey((255, 0, 255))
ui = pygame.image.load('numbers.png').convert()
ui = pygame.transform.scale(ui, (ui.get_width() * SCALE, ui.get_height() * SCALE))
ui.set_colorkey((255, 0, 255))

plansza = Plansza(screen, dane, ui_bg, ui)

plansza.load()

clock = pygame.time.Clock()
tick = 0

while zdarzenia(pygame.event.get(), plansza):
    clock.tick(25)
    tick = (tick + 1) & 3
    if tick == 0:
        plansza.ruch_pociskow()
        plansza.ruch_aktorow()
        if plansza.robbo.na_planszy():
            plansza.robbo.ruch()
        if plansza.robbo.na_planszy():
            plansza.robbo.kolizja()

        plansza.aplikuj_zniszczenia()
        plansza.draw()

        if plansza[plansza.robbo.y][plansza.robbo.x] == None:
            for item in plansza.items():
                item.destroy(plansza)
            if not filter(lambda i: not isinstance(i, Wall)\
            and not isinstance(i, Statek), plansza.items()):
                plansza.load()

    plansza.shake()
    plansza.przewin()

pygame.quit()
